package com.bris.niosocket.message.util;

import java.io.UnsupportedEncodingException;

/**
 * <p> Title: CodeUtil </p>
 * <p> Description: 编码转化工具类 </p>
 * <p> Copyright: CMBC Copyright (c) 2012 </p>
 * <p> Company: CMBC </p>
 * 
 * @author 高智
 * 
 * @version 1.0
 * @since 1.0
 */
public final class CodeUtil {

    private static final char HEX_CHARS[] = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    public static String byte2hex(byte b) {

        char hex[] = new char[2];
        hex[0] = HEX_CHARS[(Byte.valueOf(b).intValue() & 0xf0) >> 4];
        hex[1] = HEX_CHARS[Byte.valueOf(b).intValue() & 0xf];
        return new String(hex);
    }

    /**
     * byte[]转换为字符串,每个byte之间添加空格,主要用于日志,显示等
     * @param b
     * @return
     */
    public static String bytes2hex(byte[] b) {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            sb.append(byte2hex(b[i]));
            sb.append(" ");
        }
        return sb.toString();
    }

    /**
     * 将字符串转化成特定长度的byte[],如果value的长度小于destLength,则右补零。比如
     * getText(5,"1"),结果为{49,0,0,0,0}; 如果value的长度大于destLength,则截取掉一部分。比如
     * getText(2,"11111"),结果为{49,49};
     * 
     * @param destLength
     *            转化后byte[]的长度
     * @param value
     *            要转化的字符串
     * @param charset
     *            要转化的字符串的编码字符集
     * @return byte[]
     * @throws UnsupportedEncodingException
     */
    public static byte[] getText(int destLength, String value, String charset) throws UnsupportedEncodingException {

        byte[] b1 = new byte[destLength];
        int i = 0;
        if (value != null && value.length() != 0) {
            byte[] b2 = value.getBytes(charset);
            while (i < b2.length && i < destLength) {
                b1[i] = b2[i];
                i++;
            }
        }
        while (i < b1.length) {
            b1[i] = 0;
            i++;
        }
        return b1;
    }

    /**
     * 8位的byte[]数组转换成long型
     * 
     * @param mybytes
     * @return long
     */
    public static long bytes8ToLong(byte mybytes[]) {

        long tmp = ((long) (0xff & mybytes[0])) << 56 | ((long) (0xff & mybytes[1])) << 48
                | ((long) (0xff & mybytes[2])) << 40 | ((long) (0xff & mybytes[3])) << 32
                | ((long) (0xff & mybytes[4])) << 24 | (0xff & mybytes[5]) << 16 | (0xff & mybytes[6]) << 8 | 0xff
                & mybytes[7];
        return tmp;
    }

    /**
     * long类型转化成8个字节
     * 
     * @param i
     *            要转化的长整形
     * @return byte[]
     */
    public static byte[] longToBytes8(long i) {

        byte mybytes[] = new byte[8];
        mybytes[7] = (byte) (int) (255 & i);
        mybytes[6] = (byte) (int) ((65280 & i) >> 8);
        mybytes[5] = (byte) (int) ((0xff0000 & i) >> 16);
        mybytes[4] = (byte) (int) ((0xff000000 & i) >> 24);
        int high = (int) (i >> 32);
        mybytes[3] = (byte) (0xff & high);
        mybytes[2] = (byte) ((0xff00 & high) >> 8);
        mybytes[1] = (byte) ((0xff0000 & high) >> 16);
        mybytes[0] = (byte) ((0xff000000 & high) >> 24);
        return mybytes;
    }

    /**
     * int转化成4个字节的数组
     * 
     * @param i
     *            要转化的整形变量
     * @return byte[]
     */

    public static byte[] intToBytes4(int i) {

        byte mybytes[] = new byte[4];
        mybytes[3] = (byte) (0xff & i);
        mybytes[2] = (byte) ((0xff00 & i) >> 8);
        mybytes[1] = (byte) ((0xff0000 & i) >> 16);
        mybytes[0] = (byte) ((0xff000000 & i) >> 24);
        return mybytes;
    }

    /**
     * byte数组转化成无符号int类型
     * 
     * @param mybytes
     *            要转化的
     * @return int
     */
    public static int bytes4ToInt(byte mybytes[]) {

        return bytes4ToInt(mybytes, 0);
    }

    /**
     * byte数组转化成int类型
     * 
     * @param mybytes
     *            要转化的
     * @param beginIndex
     * @return int
     */
    public static int bytes4ToInt(byte mybytes[], int beginIndex) {

        int tmp = (0xff & mybytes[beginIndex]) << 24 | (0xff & mybytes[beginIndex + 1]) << 16
                | (0xff & mybytes[beginIndex + 2]) << 8 | 0xff & mybytes[beginIndex + 3];
        return tmp;
    }

    /**
     * 2个字节的byte数组转化成short类型
     * 
     * @param mybytes
     *            要转化的长度为2的byte数组
     * @return short
     */
    public static short bytes2Short(byte mybytes[]) {

        return bytes2Short(mybytes, 0);
    }

    /**
     * 2个字节的byte数组转化成short类型
     * 
     * @param mybytes
     *            要转化的长度为2的byte数组
     * @param beginIndex
     * @return short
     */
    public static short bytes2Short(byte mybytes[], int beginIndex) {

        short tmp = (short) ((0xff & mybytes[beginIndex]) << 8 | 0xff & mybytes[beginIndex + 1]);
        return tmp;
    }

    /**
     * 2个字节的byte数组转化成无符号short类型
     * 
     * @param mybytes
     *            要转化的长度为2的byte数组
     * @return int
     */
    public static int bytes2UnsignShort(byte mybytes[]) {

        return bytes2UnsignShort(mybytes, 0);
    }

    /**
     * 2个字节的byte数组转化成无符号short类型
     * 
     * @param mybytes
     *            要转化的长度为2的byte数组
     * @param beginIndex
     * @return int
     */
    public static int bytes2UnsignShort(byte mybytes[], int beginIndex) {

        int tmp = ((0xff & mybytes[beginIndex]) << 8 | 0xff & mybytes[beginIndex + 1]);
        return tmp;
    }

    // short转字节
    public static byte[] short2Byte(short i) {

        byte mybytes[] = new byte[2];
        mybytes[1] = (byte) (0xff & i);
        mybytes[0] = (byte) ((0xff00 & i) >> 8);
        return mybytes;
    }

    // 无符号short转字节
    public static byte[] unsignShort2Byte(int i) {

        if (i > 0xffff) {
            throw new IllegalArgumentException("overflow");
        }
        byte mybytes[] = new byte[2];
        mybytes[1] = (byte) (0xff & i);
        mybytes[0] = (byte) ((0xff00 & i) >> 8);
        return mybytes;
    }

    // 取字节的16进制字符串
    public static String getHexStr(byte[] bs) {

        StringBuffer retStr = new StringBuffer();
        for (int i = 0; i < bs.length; i++) {
            String hexString = Integer.toHexString(bs[i]);
            if (hexString.length() > 1) {
                retStr.append(hexString.substring(hexString.length() - 2));
            }
            else {
                retStr.append("0" + hexString);
            }
        }
        return retStr.toString();
    }

    // 16进制字符串转字节数组
    public static byte[] getByte(String byteStr) {

        if (byteStr.length() % 2 != 0) {
            byteStr = "0" + byteStr;
        }
        byte[] retByte = new byte[byteStr.length() / 2];

        for (int i = 0; i < byteStr.length() / 2; i++) {
            byte[] b = new byte[1];
            b[0] = intToBytes4(Integer.parseInt(byteStr.substring(2 * i, 2 * i + 2), 16))[3];

            retByte[i] = intToBytes4(Integer.parseInt(byteStr.substring(2 * i, 2 * i + 2), 16))[3];
        }
        return retByte;
    }

    /**
     * 去掉右补的0，转换成指定编码的字符串
     * 
     * @param bRefArr
     * @param charset
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getStr(byte[] bRefArr, String charset) throws UnsupportedEncodingException {

        int length = 0;
        for (; length < bRefArr.length; length++) {
            if (bRefArr[length] == 0) {
                break;
            }
        }
        byte[] temp = new byte[length];
        for (int i = 0; i < length; i++) {
            temp[i] = bRefArr[i];
        }
        String tempStr = new String(temp, 0, temp.length, charset);
        return tempStr;
    }

    public static void main(String[] args) {

        System.out.println(CodeUtil.getHexStr(CodeUtil.getByte("1234")));
        System.out.println(CodeUtil.getHexStr(CodeUtil.unsignShort2Byte(65535)));
        CodeUtil.getByte("12345678");
    }
}
